package com.jl.springbean;

import com.jl.springbean.util.JLPlainClassSpringBean;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 代理实现抽象为继承类
 *
 * @param <A>
 */
public class JLInvocationHandler<A> implements InvocationHandler {

    protected Class<A> classa;

    public JLInvocationHandler(Class interfaceType) {
        Type[] actualType = getGenericityType(interfaceType);
        // 取数组的第1个，肯定是A的类型
        this.classa = (Class<A>) actualType[0];
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // Object 方法，走原生方法,比如hashCode()
        if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this, args);
        }
        // 其它走本地代理
        return method.invoke(this, args);
    }

    /**
     * 获取泛型type
     */
    protected Type[] getGenericityType(Class interfaceType) {
        // 获取当前类上的泛型类型
        ParameterizedType parameterizedType = (ParameterizedType) interfaceType.getGenericInterfaces()[0];
        // 获取泛型对应的真实类型(泛型真实类型在很多场合需要使用)
        Type[] actualType = parameterizedType.getActualTypeArguments();
        return actualType;
    }

    /**
     * 获取bean 因为无法注入bean，故提供该方法自行获取想要的bean
     */
    protected <B> B getBean(Class<B> beanClass) {
        return JLPlainClassSpringBean.getBean(beanClass);
    }

}
